import { useState, useEffect, useCallback } from 'react';
import { MEDIA_CONSTRAINTS } from '@/utils/constants';
import { getErrorMessage } from '@/utils/helpers';

export interface MediaDevice {
  deviceId: string;
  label: string;
  kind: MediaDeviceKind;
}

export interface UseMediaDevicesReturn {
  // 设备列表
  audioInputDevices: MediaDevice[];
  videoInputDevices: MediaDevice[];
  audioOutputDevices: MediaDevice[];
  
  // 当前选中的设备
  selectedAudioInput: string;
  selectedVideoInput: string;
  selectedAudioOutput: string;
  
  // 权限状态
  hasAudioPermission: boolean;
  hasVideoPermission: boolean;
  
  // 方法
  requestPermissions: () => Promise<void>;
  switchAudioInput: (deviceId: string) => Promise<void>;
  switchVideoInput: (deviceId: string) => Promise<void>;
  switchAudioOutput: (deviceId: string) => Promise<void>;
  refreshDevices: () => Promise<void>;
  
  // 状态
  isLoading: boolean;
  error: string | null;
}

export const useMediaDevices = (): UseMediaDevicesReturn => {
  const [audioInputDevices, setAudioInputDevices] = useState<MediaDevice[]>([]);
  const [videoInputDevices, setVideoInputDevices] = useState<MediaDevice[]>([]);
  const [audioOutputDevices, setAudioOutputDevices] = useState<MediaDevice[]>([]);
  
  const [selectedAudioInput, setSelectedAudioInput] = useState<string>('');
  const [selectedVideoInput, setSelectedVideoInput] = useState<string>('');
  const [selectedAudioOutput, setSelectedAudioOutput] = useState<string>('');
  
  const [hasAudioPermission, setHasAudioPermission] = useState(false);
  const [hasVideoPermission, setHasVideoPermission] = useState(false);
  
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 检查媒体设备权限
  const checkPermissions = useCallback(async () => {
    try {
      // 检查音频权限
      const audioPermission = await navigator.permissions.query({ name: 'microphone' as PermissionName });
      setHasAudioPermission(audioPermission.state === 'granted');
      
      // 检查视频权限
      const videoPermission = await navigator.permissions.query({ name: 'camera' as PermissionName });
      setHasVideoPermission(videoPermission.state === 'granted');
    } catch (error) {
      // 某些浏览器可能不支持 permissions API
      console.warn('无法检查权限状态:', error);
    }
  }, []);

  // 获取媒体设备列表
  const getDevices = useCallback(async () => {
    try {
      const devices = await navigator.mediaDevices.enumerateDevices();
      
      const audioInputs: MediaDevice[] = [];
      const videoInputs: MediaDevice[] = [];
      const audioOutputs: MediaDevice[] = [];
      
      devices.forEach(device => {
        const mediaDevice: MediaDevice = {
          deviceId: device.deviceId,
          label: device.label || `${device.kind} ${device.deviceId.slice(0, 8)}`,
          kind: device.kind,
        };
        
        switch (device.kind) {
          case 'audioinput':
            audioInputs.push(mediaDevice);
            break;
          case 'videoinput':
            videoInputs.push(mediaDevice);
            break;
          case 'audiooutput':
            audioOutputs.push(mediaDevice);
            break;
        }
      });
      
      setAudioInputDevices(audioInputs);
      setVideoInputDevices(videoInputs);
      setAudioOutputDevices(audioOutputs);
      
      // 设置默认设备
      if (audioInputs.length > 0 && !selectedAudioInput) {
        setSelectedAudioInput(audioInputs[0].deviceId);
      }
      if (videoInputs.length > 0 && !selectedVideoInput) {
        setSelectedVideoInput(videoInputs[0].deviceId);
      }
      if (audioOutputs.length > 0 && !selectedAudioOutput) {
        setSelectedAudioOutput(audioOutputs[0].deviceId);
      }
      
    } catch (error) {
      console.error('获取媒体设备失败:', error);
      setError(getErrorMessage(error));
    }
  }, [selectedAudioInput, selectedVideoInput, selectedAudioOutput]);

  // 请求媒体权限
  const requestPermissions = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    
    try {
      // 请求音频和视频权限
      const stream = await navigator.mediaDevices.getUserMedia(MEDIA_CONSTRAINTS);
      
      // 获取权限后立即停止流
      stream.getTracks().forEach(track => track.stop());
      
      setHasAudioPermission(true);
      setHasVideoPermission(true);
      
      // 重新获取设备列表（现在应该有标签了）
      await getDevices();
      
    } catch (error: any) {
      console.error('请求媒体权限失败:', error);
      setError(getErrorMessage(error));
      
      // 根据错误类型设置权限状态
      if (error.name === 'NotAllowedError') {
        setHasAudioPermission(false);
        setHasVideoPermission(false);
      }
    } finally {
      setIsLoading(false);
    }
  }, [getDevices]);

  // 切换音频输入设备
  const switchAudioInput = useCallback(async (deviceId: string) => {
    try {
      setSelectedAudioInput(deviceId);
      // 这里可以添加实际切换设备的逻辑
      console.log('切换音频输入设备:', deviceId);
    } catch (error) {
      console.error('切换音频输入设备失败:', error);
      setError(getErrorMessage(error));
    }
  }, []);

  // 切换视频输入设备
  const switchVideoInput = useCallback(async (deviceId: string) => {
    try {
      setSelectedVideoInput(deviceId);
      // 这里可以添加实际切换设备的逻辑
      console.log('切换视频输入设备:', deviceId);
    } catch (error) {
      console.error('切换视频输入设备失败:', error);
      setError(getErrorMessage(error));
    }
  }, []);

  // 切换音频输出设备
  const switchAudioOutput = useCallback(async (deviceId: string) => {
    try {
      setSelectedAudioOutput(deviceId);
      // 这里可以添加实际切换设备的逻辑
      console.log('切换音频输出设备:', deviceId);
    } catch (error) {
      console.error('切换音频输出设备失败:', error);
      setError(getErrorMessage(error));
    }
  }, []);

  // 刷新设备列表
  const refreshDevices = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    
    try {
      await getDevices();
    } catch (error) {
      console.error('刷新设备列表失败:', error);
      setError(getErrorMessage(error));
    } finally {
      setIsLoading(false);
    }
  }, [getDevices]);

  // 监听设备变化
  useEffect(() => {
    const handleDeviceChange = () => {
      console.log('媒体设备发生变化');
      getDevices();
    };

    // 检查浏览器是否支持设备变化监听
    if (navigator.mediaDevices && navigator.mediaDevices.addEventListener) {
      navigator.mediaDevices.addEventListener('devicechange', handleDeviceChange);
      
      return () => {
        navigator.mediaDevices.removeEventListener('devicechange', handleDeviceChange);
      };
    }
  }, [getDevices]);

  // 初始化
  useEffect(() => {
    const initialize = async () => {
      await checkPermissions();
      await getDevices();
    };
    
    initialize();
  }, [checkPermissions, getDevices]);

  return {
    audioInputDevices,
    videoInputDevices,
    audioOutputDevices,
    selectedAudioInput,
    selectedVideoInput,
    selectedAudioOutput,
    hasAudioPermission,
    hasVideoPermission,
    requestPermissions,
    switchAudioInput,
    switchVideoInput,
    switchAudioOutput,
    refreshDevices,
    isLoading,
    error,
  };
};